home *** CD-ROM | disk | FTP | other *** search
/ Hackers Handbook - Millenium Edition / Hackers Handbook.iso / files / c_scripts / sl0scan.perl < prev    next >
Internet Message Format  |  1999-04-11  |  12KB

  1. Date: Tue, 9 Feb 1999 20:53:34 -0500
  2. From: miff <miff@BLUE.9MM.COM>
  3. To: BUGTRAQ@netspace.org
  4. Subject: sl0scan (ambiguous source portscanner)
  5.  
  6. hello all,
  7.  
  8. I hear that maybe nmap does something similar to this, but I'm posting it anyway to see if there is
  9. enough interest for me to continue developing it.  This is based on some code that I have been evolving
  10. for a while now.
  11.  
  12. sl0scan features:
  13. - you select which ports to scan using comma separated lists and ranges at runtime
  14. - *identical* scans sent from as many hosts as you like
  15. - random generation of dummy hosts, or it can read a file of desired fake scanning sources (or both).
  16. - choose at what sequence to insert the real scan (say, #500 out of 1000 scans)
  17. - status shown on screen
  18.  
  19. also:
  20. - written in easily modifiable perl;  all packet components are in variables
  21.  
  22. sl0scan drawbacks:
  23. - you have to sniff the response.  This really isnt so bad;  you just do "tcpdump src <scantarget>" in a
  24. seperate window and look for the big "R" or "S" from each port.  (S means the port was open).  If there
  25. is interest, I'll fold in the packet capture function in the next release.
  26. - it can be slow depending on how you use it
  27. - tcp only at this release
  28.  
  29.  
  30. #!/usr/bin/perl
  31. #
  32. #  sl0scan v0.1
  33. #   perl spoofer/scanner
  34. #   based on lego
  35. #
  36. #  written by miff  Jan 1999
  37. #
  38. #  i wrote this in response to all the
  39. #  email i got from lego saying:
  40. #  "i'm not getting a response from the
  41. #  portscan!!&^@#$"
  42. #
  43. #  this version requests the following:
  44. #    - which ports to scan
  45. #    - how many fake hosts to use
  46. #    - the "real" ip (any sniffable ip)
  47. #    - an optional file of "real" fakes
  48. #    - when to insert the real scan
  49. #
  50. #  you are responsible for sniffing the response,
  51. #  at this point.  maybe that'll be automatic
  52. #  in the future.
  53. #
  54. # shouts:  b_, X, kubiak, shinex, xyg, ReDragon, #9mm
  55. #  also:  Clovis  (where ya at h0mez?)
  56. #
  57. # best musical artist:  mike patton.
  58. #
  59.  
  60. use Socket;
  61. use strict    qw(refs, subs);
  62.  
  63. my $delay = 1;  # delay in seconds between scans.  its really important
  64. #        not to end up with a synflood here, that will break the
  65. #        scan.  use a large real fake file to avoid DoS.
  66.  
  67. my $input, $dummy;
  68. print "Welcome to sl0scan, the slowest scanner on the net.\n";
  69. print "This program sends out a deluge of fake scans, and inserts \n";
  70. print " a real scan somewhere in between.  In this version, you \n";
  71. print " must fire up a sniffer and watch for the responses to \n";
  72. print " the real scan...  Hope you know what to look for \n";
  73. print "\n";
  74. print "ready?\n";
  75. $dummy = <>;
  76. print "good.  here's where we axe you the 5 imp0tent questi0nz:\n\n";
  77. print "1.)  what is the IP ADDY or HOSTNAME of the target? \n";
  78. $input = <>;
  79. chop $input;
  80. $target_box = $input;
  81. print "got $input.\n\n\n";
  82. print "2.)  what be the true source of the scan? (any sniffable ip will do) \n";
  83. $input = <>;
  84. chop $input;
  85. $true_source = $input;
  86. print "got $input.\n\n\n";
  87. print "3.)  how many fakes should we dump on this homies fro? \n";
  88. print "note:  number of fakes will directly affect the sl0ness of the scan\n";
  89. print " to the tune of at least 1 second per host.  we don wanna dos here.. \n";
  90. print " otoh, lots of fakes increase your invisibility \n";
  91. $input = <>;
  92. chop $input;
  93. $num_fakes = $input;
  94. print "got $input.  <-- hope that was a number...\n\n\n";
  95. print "4.)  which ports should we check?  (IMPORTANT) \n";
  96. print " i recommend as few as possible, as this will *really* slow shit down\n";
  97. print "enter ports in the following format:  COMMA DELIMITED, indicate ranges with dash\n";
  98. print " example:  i want to scan ports 22 23 25 80 and 130-140.  i say: \n";
  99. print "22,23,25,80,130-140\n";
  100. print "avoid spaces and extra shit.  save that for another time. \n";
  101. $input = <>;
  102. chop $input;
  103. $portlist = $input;
  104. print "got $input. <-- if you screwed that up, bad shit is gonna happen.\n\n\n";
  105. print "5.)  At what sequence would you like the real scan inserted? \n";
  106. print "note:  this number must be <= the total number of fakes...\n";
  107. $input = <>;
  108. chop $input;
  109. $real_seq = $input;
  110. $real_seq--;  #gotta decrement; we start wit 0
  111. print "got $input.  <-- hope that was a number...\n\n\n";
  112. print "6.)  ok last one.  Would you like to use a file of desired fakes?\n";
  113. print "this gives you the advantage of choosing the fake ips, and \n";
  114. print "avoiding the situation that all of the fake scans came from \n";
  115. print "non-existent ips.  i'd recommend using a large file here \n\n";
  116. print "also, if you use all fake ips, even with the one second delay, \n";
  117. print "you stand a greater chance of DOS'ing the target.  which is bad.\n\n";
  118. print "fyi, the format for the file is 1 ip or hostname per line, no extra shit. \n\n";
  119. print " IF YOU WANT TO USE SUCH A FILE, enter the filename here:\n";
  120. $input = <>;
  121. chop $input;
  122. $frofile = $input;
  123. print "got $input.  <-- hope that was a real file...\n\n\n";
  124. print "OK FOO, WE READY.  YOU READY?\n";
  125. $dummy = <>;
  126.  
  127. my @frobobs;
  128. my $frocount = -1;
  129. # ok, first order of bidniss:  lets get that file open if it exists:
  130. if ($frofile ne '') {
  131.   if (-e $frofile) {
  132.     #we got a file...
  133.     open (FROFILE, $frofile) || die "cant open file, kid";
  134.     while ($input = <FROFILE>) {
  135.         chop $input;
  136.         $frocount++;
  137.         @frobobs[$frocount] = $input;
  138.     }
  139.     close (FROFILE);
  140.     # while we're at it, lets cal the percent of total fakes:
  141.     $fro_percent = $frocount * 100 / $num_fakes;
  142.   }
  143. }
  144.  
  145. my $scancount = 0;
  146. my $src_box, $src_port;
  147. srand(time ^ $$);
  148.  
  149. while ($scancount < $num_fakes) {
  150.     # main driver routine
  151.     if ($scancount == $real_seq) {
  152.         #this is the real deal
  153.         print "real scan!! (from $true_source) \n\n";
  154.         $src_box = $true_source;
  155.     } else {
  156.         # grab a random number between 0 and $num_fakes
  157.         if ($randum > $frocount) {
  158.             #create one
  159.             my $rand1 = int(rand(230)) + 20;
  160.                         my $rand2 = int(rand(255));
  161.                         my $rand3 = int(rand(255));
  162.                         my $rand4 = int(rand(255));
  163.                         $src_box = $rand1 . "." . $rand2 . "." . $rand3 . "." . $rand4;
  164.                         #for debugging:
  165.             print "scan from $src_box \n";
  166.         } else {
  167.             # use the array
  168.             $randum = int(rand($num_fakes));
  169.             $src_box = @frobobs[$randum];
  170.             print "we gon fro from $src_box \n";
  171.         }
  172.     }
  173.     # now send the scan
  174.     sc4n($target_box,$portlist,$src_box,$fake_port);
  175.     
  176.     # now sleep to avoid DoS:
  177.     sleep($delay);
  178.  
  179.     $scancount++;
  180. }
  181.  
  182.  
  183. sub sc4n  {
  184.     my ($dest_host,$dest_ports,$src_host,$src_port) = @_;
  185.  
  186.     #print "in scan, got $dest_host,$dest_ports,$src_host,$src_port\n\n";
  187.  
  188.     #set constants:
  189.     my ($PROTO_RAW) = 255; # from /etc/protocols
  190.     my ($PROTO_IP) = 0;  #ditto
  191.     my ($IP_HDRINCL) = 1;  #we set the ip header, thanks
  192.  
  193.     #look up mah shit...
  194.     $dest_host = (gethostbyname($dest_host))[4];
  195.     $src_host = (gethostbyname($src_host))[4];
  196.  
  197.     #time to open a raw socket....
  198.     socket(S, AF_INET, SOCK_RAW, $PROTO_RAW) || die $!;
  199.  
  200.     #raw socket should be open...
  201.     #now set the bad boy up...
  202.     setsockopt(S, $PROTO_IP, $IP_HDRINCL, 1);
  203.  
  204.     # here we need to interpret the port list:
  205.     my @ports1 = split (",",$dest_ports);
  206.  
  207.     my $psplit,$rcount,$range_low,$range_hi;
  208.     my $p2count = 0;
  209.     my @ports2;
  210.     my @range;
  211.  
  212.     foreach $psplit (@ports1) {
  213.         if ($psplit =~ '-') {
  214.             # we have a range
  215.             @range = split("-",$psplit);
  216.             $range_low = @range[0];
  217.             $range_hi = @range[1];
  218.             $rcount = $range_low;
  219.             while ($rcount <= $range_hi) {
  220.                 @ports2[$p2count] = $rcount;
  221.                 $p2count++;
  222.                 $rcount++;
  223.             }
  224.         } else {
  225.             @ports2[$p2count] = $psplit;
  226.             $p2count++;
  227.         }
  228.     }
  229.  
  230.     my $port;
  231.  
  232.     foreach $port (@ports2) {
  233.         #build a tcp header:
  234.  
  235.         #vary the ports in here...
  236.         $src_port = int(rand(60000));
  237.         
  238.         my ($packet) = givehead($src_host, $src_port, $dest_host, $port, $data);
  239.         #bust out the destination...
  240.         my ($dest) = pack('S n a4 x8', AF_INET, $port, $dest_host);
  241.         #send a fux0ring packet
  242.         send (S,$packet,0, $dest);
  243.     }
  244.  
  245. }
  246.  
  247. sub givehead {
  248.     my ($src_host, $src_port, $dest_host, $dest_port, $data) = @_;
  249.  
  250.     #HERE WE PLAY WITH THE INSIDES OF THE TCP PIECE
  251.     #AND CALC THE TCP HDR CHECKSUM.
  252.     my $hdr_cksum = 0;  # we set it to 0 so we can calculate it
  253.     my $zero = 0;  #might need a zero from time to time
  254.     my $proto_tcp = 6;  # the protocol number for tcp
  255.     my ($tcplength) = 20; # 20 byte tcp hdr; no data
  256.     # IF YOU ADD DATA, MAKE SURE TO ADD ITS PACKED LENGTH
  257.     # TO THE TCPLENGTH HERE!!!
  258.     # all of the source and destination infoz is passed to us
  259.     # screw wit it in the parent routine...
  260.     my $syn = 790047533;  # random syn;  try to keep it under 32 bits :)
  261.     my $ack = 0;  # zero ack;  try to keep it under 32 bits :)
  262.     my $tcp_4bit_hdrlen = "5"; # 5 * 32bit (4 byte) = 20 bytes
  263.     my $tcp_4bit_reserved = 0; # reserved for 0
  264.     my $hdr_n_reserved = $tcp_4bit_hdrlen . $tcp_4bit_reserved;  # pack them together
  265.     my $tcp_urg_bit = 0;  # URGENT POINTER BIT
  266.     my $tcp_ack_bit = 0;  # ACKNOWLEDGEMENT FIELD BIT
  267.     my $tcp_psh_bit = 0;  # PUSH REQUEST BIT
  268.     my $tcp_rst_bit = 0;  # RST (RESET CONNXION) BIT
  269.     my $tcp_syn_bit = 1;  # SYN FLAG BIT  #its a syn!!
  270.     my $tcp_fin_bit = 0;  # FIN FLAG BIT
  271.     # here we put together 2 reserved fields and the 6 flags to pack as binary.
  272.     my $tcp_codebits = $zero . $zero . $tcp_urg_bit . $tcp_ack_bit . $tcp_psh_bit .
  273.         $tcp_rst_bit . $tcp_syn_bit . $tcp_fin_bit;
  274.     my $tcp_windowsize = 124;  # default window size
  275.     my $tcp_urgent_pointer = 0;  # urgent pointer
  276.  
  277.  
  278.     # the following is not a tcp header per se, but a pseudo header
  279.     # used to calculate the tcp checksum.  yes, its a pain in the ass.
  280.     my ($pseudo_tcp) = pack ('a4 a4 C C
  281.                 n n n
  282.                 N N
  283.                 H2 B8
  284.                 n v n',
  285.             $src_host,$dest_host,$zero,$proto_tcp,
  286.             $tcplength,$src_port,$dest_port,
  287.             $syn,$ack,
  288.             $hdr_n_reserved,$tcp_codebits,
  289.             $tcp_windowsize,$zero,$tcp_urgent_pointer);
  290.  
  291.     my ($tcp_chksum) = &checkfro($pseudo_tcp);
  292.  
  293.  
  294.     # PLAY WITH THE INNARDS OF THE IP PIECE HERE!!!
  295.     my $ip_version = "4";  # (nybble) tcp/ip version number (current is 4)
  296.     my $ip_hedlen = "5";  # (nybble) number of 32-bit words in ip header
  297.     my $ver_n_hlen = $ip_version . $ip_hedlen; # we pack 2 nybbles together
  298.     my $ip_tos = "00";  # (byte) ip type-of-service
  299.     my ($totlength) = $tcplength + 20; #tcp + 20 byte ip hdr ##
  300.     ## we'll pack totlength into 2 bytes in the packet
  301.     my $ip_fragment_id = 31337;  # 2 bytes as well.
  302.     my $ip_3bit_flags = "010"; # ip fragmentation flags (3 bits) (frag, do not frag)
  303.     my $ip_13bit_fragoffset = "0000000000000";  #fragment offset
  304.     my $ip_flags_n_frags = $ip_3bit_flags . $ip_13bit_fragoffset;
  305.     my $ip_ttl = 64;  # 64 seconds / hops
  306.     # we have proto_tcp from above...  my $proto_tcp = 6;
  307.     # we have hdr_checksum from above...
  308.     # all source and destination infoz is passed to us (it
  309.     #  gets set in parent routine)
  310.     # change $syn and $ack above in tcp section
  311.     # in fact, everything else in the packet is set above.
  312.     
  313.  
  314.     my ($hdr) = pack ('H2 H2 n n
  315.                 B16 C2
  316.                n a4 a4
  317.                n n
  318.                N N
  319.                H2 B8
  320.                n v n',
  321.         $ver_n_hlen, $ip_tos, $totlength, $ip_fragment_id,
  322.         $ip_flags_n_frags,$ip_ttl, $proto_tcp,
  323.         $hdr_cksum, $src_host, $dest_host,
  324.         # end of ip header, begin tcp header
  325.         $src_port, $dest_port,
  326.         $syn,$ack,
  327.         $hdr_n_reserved,$tcp_codebits,
  328.         $tcp_windowsize,$tcp_chksum,$tcp_urgent_pointer);
  329.  
  330.     return $hdr;
  331. }
  332.  
  333. sub checkfro {
  334.     #dis sekzhun robbed from someplace else....
  335.     my (
  336.         $msg            # The message to checkfro
  337.         ) = @_;
  338.     my ($len_msg,       # Length of the message
  339.         $num_short,     # The number of short words in the message
  340.         $short,         # One short word
  341.         $chk            # The checkfro
  342.         );
  343.  
  344.     $len_msg = length($msg);
  345.     $num_short = $len_msg / 2;
  346.     $chk = 0;
  347.     foreach $short (unpack("S$num_short", $msg))
  348.     {
  349.         $chk += $short;
  350.     }                                   # Add some lead
  351.     $chk += unpack("C", substr($msg, $len_msg - 1, 1)) if $len_msg % 2;
  352.     $chk = ($chk >> 16) + ($chk & 0xffff);      # bust out mah fro pic
  353.     return(~(($chk >> 16) + $chk) & 0xffff);    # spray some jheri
  354. }
  355.  
  356.  
  357.